package com.blt.govdata.filters;

import com.blt.govdata.core.constants.Constants;
import com.blt.govdata.core.token.TokenKey;
import com.blt.govdata.core.web.NeedLoginException;
import com.blt.govdata.core.web.TokenException;
import com.blt.govdata.utils.DESPlus;
import org.apache.catalina.filters.RemoteIpFilter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by AustinGJ on 2018/3/26.
 */
@Configuration
public class WebFilter {

    @Bean
    public RemoteIpFilter remoteIpFilter() {
        return new RemoteIpFilter();
    }

    @Bean
    public FilterRegistrationBean testFilterRegistration() {
        //配置无需过滤的路径或者静态资源，如：css，imgage等  
        StringBuffer excludedUriStr = new StringBuffer();
        excludedUriStr.append("/tSysUser/login*");
        excludedUriStr.append(",");
        excludedUriStr.append("/tSysUser/token*");
        excludedUriStr.append(",");
        excludedUriStr.append("/upload/file*");
        excludedUriStr.append(",");
        excludedUriStr.append("/excel/*");
        excludedUriStr.append(",");
        excludedUriStr.append("/favicon.ico");
        excludedUriStr.append(",");
        excludedUriStr.append("/js/*");

        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("excludedUri", excludedUriStr.toString());
        registration.setName("CustomFilter");
        registration.setOrder(1);
        return registration;
    }


    public class MyFilter implements Filter {

        private String[] excludedUris;

        @Override
        public void destroy() {
            // TODO Auto-generated method stub  
        }

        @Override
        public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
                throws IOException, ServletException {
            // TODO Auto-generated method stub  
            HttpServletRequest request = (HttpServletRequest) srequest;
            HttpServletResponse response = (HttpServletResponse) sresponse;
            System.out.println("This is CustomFilter,url :" + request.getRequestURI());
            String uri = request.getServletPath();
            if (isExcludedUri(uri)) {
                filterChain.doFilter(srequest, sresponse);
            } else {
                if ("OPTIONS".equals(request.getMethod())) {//这里通过判断请求的方法，判断此次是否是预检请求，如果是，立即返回一个204状态吗，标示，允许跨域；预检后，正式请求，这个方法参数就是我们设置的post了
                    response.setStatus(204); //HttpStatus.SC_NO_CONTENT = 204
                    filterChain.doFilter(srequest, sresponse);
                } else {
                    String token = request.getHeader(Constants.TOKEN);
                    if(StringUtils.isBlank(token)) throw new NeedLoginException("需要登录");
                    token = token.replaceFirst("Bearer ", "");
                    String key;
                    try {
                        String ss = new DESPlus().decode(token);
                        key = ss.split(",")[0];
                    } catch (Exception e) {
                        throw new TokenException("token验证失败");
                    }
                    if (StringUtils.equals(TokenKey.KEY, key)) filterChain.doFilter(srequest, sresponse);
                    else throw new TokenException("token验证失败");
                }
            }
        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // TODO Auto-generated method stub  
            excludedUris = filterConfig.getInitParameter("excludedUri").split(",");
        }

        private boolean isExcludedUri(String uri) {
            if (excludedUris == null || excludedUris.length <= 0) {
                return false;
            }
            for (String ex : excludedUris) {
                uri = uri.trim();
                ex = ex.trim();
                if (uri.toLowerCase().matches(ex.toLowerCase().replace("*", ".*")))
                    return true;
            }
            return false;
        }

    }

} 